cmake_minimum_required(VERSION 3.14)

project(StdCache LANGUAGES CXX)

# Default to a sensible build type if none is provided
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
    set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE)
    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel")
endif()

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

include(CheckCXXCompilerFlag)
if(MSVC)
    set(_stdcxx17_flag "/std:c++17")
else()
    set(_stdcxx17_flag "-std=c++17")
endif()
check_cxx_compiler_flag("${_stdcxx17_flag}" STD_CACHE_COMPILER_SUPPORTS_CXX17)

find_package(Threads REQUIRED)

set(_stdcache_headers
    cache_interface.h
    lru_cache.h
    memory_cache.h
    disk_cache.h
    hierarchical_cache.h
)

add_executable(cache_demo cache_demo.cpp ${_stdcache_headers})
target_link_libraries(cache_demo PRIVATE Threads::Threads)
target_compile_features(cache_demo PRIVATE cxx_std_11)
if(MSVC)
    target_compile_options(cache_demo PRIVATE /W4 /permissive-)
else()
    target_compile_options(cache_demo PRIVATE -Wall -Wextra -Wpedantic $<$<CONFIG:Release>:-O2>)
endif()
target_compile_definitions(cache_demo PRIVATE $<$<CONFIG:Debug>:DEBUG>)

if(STD_CACHE_COMPILER_SUPPORTS_CXX17)
    add_executable(main main.cpp ${_stdcache_headers})
    target_link_libraries(main PRIVATE Threads::Threads)
    target_compile_features(main PRIVATE cxx_std_17)
    if(MSVC)
        target_compile_options(main PRIVATE /W4 /permissive-)
    else()
        target_compile_options(main PRIVATE -Wall -Wextra -Wpedantic $<$<CONFIG:Release>:-O2>)
    endif()
    target_compile_definitions(main PRIVATE $<$<CONFIG:Debug>:DEBUG>)
else()
    message(STATUS "C++17 not supported by ${CMAKE_CXX_COMPILER}; skipping main target.")
endif()

option(STD_CACHE_BUILD_SIMPLE_TEST "Build the simple LRU smoke test" OFF)
if(STD_CACHE_BUILD_SIMPLE_TEST)
    add_executable(simple_test simple_test.cpp ${_stdcache_headers})
    target_link_libraries(simple_test PRIVATE Threads::Threads)
    target_compile_features(simple_test PRIVATE cxx_std_11)
    if(MSVC)
        target_compile_options(simple_test PRIVATE /W4 /permissive-)
    else()
        target_compile_options(simple_test PRIVATE -Wall -Wextra -Wpedantic)
    endif()
    target_compile_definitions(simple_test PRIVATE $<$<CONFIG:Debug>:DEBUG>)
endif()
